import time

from django.utils.deprecation import MiddlewareMixin
import logging
from django.http import JsonResponse

from src.utils.makeJwt import jwt_decode
from src.utils.Tools import query_to_dict
from src.utils.ReturnStatus import ResponseStatus
from common.models import TbMiniappUser
from src.utils.constant import ACCESS_TOKEN_EXPIRY
from common.tool.userTool import checkPassword

errlog = logging.getLogger("err")


class CheckToken(MiddlewareMixin):
    username = ""
    # ignore_url = ["miniLogin", "login", "courseTaskSecurityPaySucess", "securityDepositPaySucess", "getCourseTask"]
    ignore_url = [
        "/common/miniLogin",
        "/common/login",
        "/common/getCourseTask",
        "/leaderboard/sitelist",
        "/leaderboard/siteDetail"
    ]

    def process_request(self, request):
        try:
            if request.path_info in self.ignore_url or \
                    request.path.split("/")[1] == "static":
                pass
            else:
                # 获取参数
                # --- start ---
                token = request.headers.get("Authorization")
                # if request.method == "GET":
                #     data = request.GET.dict()
                # else:
                #     if request.content_type == "multipart/form-data":
                #         data = request.POST.dict()
                #     else:
                #         data = eval(request.body.decode())
                # --- end ---
                # 解析 token
                # --- start ---
                if token is None:
                    return ResponseStatus().unlogin(message="请登录")
                try:
                    payload = jwt_decode(token)
                except Exception as e:
                    errlog.error(str(e))
                    return ResponseStatus().failed(message=str(e))
                # --- end ---
                # 验证用户名密码并获取userid
                # -- start ---
                username = payload["username"]
                password = payload["password"]
                try:
                    user = TbMiniappUser.objects.get(username=username)
                except TbMiniappUser.DoesNotExist:
                    return ResponseStatus().unlogin(message="请先登录")
                if checkPassword(user, password):
                    self.username = username
                else:
                    return ResponseStatus().failed(message="用户名密码错误")
                # --- end ---
                # 验证token是否过期
                # --- start ---
                try:
                    now = time.time()  # 现在
                    later_exprie = now - ACCESS_TOKEN_EXPIRY  # 最晚过期时间
                    create_timestamp = payload['create_time']
                    if later_exprie > create_timestamp:
                        return ResponseStatus().token_outtime(message="token 已经过期 请重新登录")
                except Exception as e:
                    errlog.error(e)
                    return ResponseStatus().failed(message=str(e))
                # --- end ---
        except Exception as e:
            errlog.error(e)
            return ResponseStatus().failed(message=str(e))

    def process_view(self, request, view_func, args, kwargs):
        if request.path_info in self.ignore_url or \
                request.path.split("/")[1] == "static":
            try:
                return view_func(request, *args, **kwargs)
            except Exception as e:
                errlog.error(e)
                return ResponseStatus().failed(message=str(e))
        else:
            try:
                user = TbMiniappUser.objects.get(username=self.username)
            except TbMiniappUser.DoesNotExist:
                return ResponseStatus().failed(message="用户不存在")
            try:
                request.META["USER"] = user
                return view_func(request)
            except Exception as e:
                errlog.error(e)
                return ResponseStatus().failed(message=str(e))
